/*
 * This file is part of LibrePlan
 *
 * Copyright (C) 2010-2011 Igalia, S.L.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.libreplan.web.exceptionDays;

import static org.libreplan.web.I18nHelper._;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.Validate;
import org.libreplan.business.calendars.daos.ICalendarExceptionTypeDAO;
import org.libreplan.business.calendars.entities.CalendarExceptionType;
import org.libreplan.business.common.IntegrationEntity;
import org.libreplan.business.common.daos.IConfigurationDAO;
import org.libreplan.business.common.entities.EntityNameEnum;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.common.exceptions.ValidationException;
import org.libreplan.web.common.IntegrationEntityModel;
import org.libreplan.web.common.concurrentdetection.OnConcurrentModification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.zkoss.util.IllegalSyntaxException;

/**
 * @author Diego Pino <dpino@igalia.com>
 */
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@OnConcurrentModification(goToPage = "/excetiondays/exceptionDays.zul")
public class CalendarExceptionTypeModel extends IntegrationEntityModel implements ICalendarExceptionTypeModel {

    @Autowired
    private ICalendarExceptionTypeDAO calendarExceptionTypeDAO;

    @Autowired
    private IConfigurationDAO configurationDAO;

    private CalendarExceptionType calendarExceptionType;

    @Override
    @Transactional(readOnly = true)
    public void initCreate() {

        Boolean generateCode = configurationDAO.getConfiguration().getGenerateCodeForCalendarExceptionType();
        calendarExceptionType = CalendarExceptionType.create();
        calendarExceptionType.setCode("");
        if (generateCode) {
            setDefaultCode();
        }
        calendarExceptionType.setCodeAutogenerated(generateCode);
    }

    @Override
    public CalendarExceptionType getExceptionDayType() {
        return calendarExceptionType;
    }

    @Override
    @Transactional(readOnly=true)
    public List<CalendarExceptionType> getExceptionDayTypes() {
        return calendarExceptionTypeDAO.getAll();
    }

    @Override
    @Transactional
    public void confirmSave() throws ValidationException {
        calendarExceptionTypeDAO.save(calendarExceptionType);
    }

    @Override
    @Transactional
    public void confirmDelete(CalendarExceptionType exceptionType) throws InstanceNotFoundException, IllegalSyntaxException {
        if (calendarExceptionTypeDAO.hasCalendarExceptions(exceptionType)) {

            throw new IllegalSyntaxException(
                    _("Cannot remove {0}, since it is being used by some exception day", exceptionType.getName()));
        }
        if (!exceptionType.isNewObject()) {
            calendarExceptionTypeDAO.remove(exceptionType.getId());
        }
    }

    @Override
    @Transactional(readOnly = true)
    public void initEdit(CalendarExceptionType exceptionType) {
        Validate.notNull(exceptionType);
        this.calendarExceptionType = getFromDB(exceptionType);
        initOldCodes();
    }

    private CalendarExceptionType getFromDB(CalendarExceptionType exceptionType) {
        return getFromDB(exceptionType.getId());
    }

    private CalendarExceptionType getFromDB(Long id) {
        try {
            return calendarExceptionTypeDAO.find(id);
        } catch (InstanceNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    public EntityNameEnum getEntityName() {
        return EntityNameEnum.CALENDAR_EXCEPTION_TYPE;
    }

    public Set<IntegrationEntity> getChildren() {
        return new HashSet<>();
    }

    public IntegrationEntity getCurrentEntity() {
        return this.calendarExceptionType;
    }
}
